﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Citi.RoutineBase;
using Microsoft.SharePoint.Client;

namespace Citi.GenericApplications.SchedulerUi
{
    public class UploadSharepoint : IExecutableRoutine
    {
        private static ClientContext ClientContext;

        public IEnumerable<RoutineParameter> Parameters
        {
            get
            {
                return new List<RoutineParameter> { 
                    new RoutineParameter{ Description = "Sharepoint site Full URL. e.g. https://globalconsumer.collaborationtools.consumer.citigroup.net/sites/SITE_NAME", Name ="SharepointUrl", Nullable = false, Required = true, Type = typeof(string)},
                    new RoutineParameter{ Description = "Sharepoint List Name", Name ="ListName", Nullable = false, Required = true, Type = typeof(string)},
                    new RoutineParameter{ Description = @"Upload File or Directory. e.g. 'C:\Temp\Imagem.jpg' OR 'C:\Temp\Reports'", Name ="UploadPath", Nullable = false, Required = true, Type = typeof(string)},
                    new RoutineParameter{ Description = "Search pattern to get files on the Directory", Name ="SearchPatternFile", Nullable = true, Required = false, Type = typeof(string)},
                    new RoutineParameter{ Description = @"Sharepoint Folder to upload files. e.g. Reports\Report_Name\Year", Name ="SPFolderToUpload", Nullable = false, Required = true, Type = typeof(string)},
                    new RoutineParameter{ Description = "Overwrite existing file?", Name ="OverwriteExistingFile", Nullable = false, Required = true, Type = typeof(bool)},
                };
            }
        }

        public void Rollback(ref ICurrentAction currentAction, Dictionary<string, object> parameters)
        {

        }

        public void Start(DateTime scheduledDate, ref ICurrentAction currentAction, Dictionary<string, object> parameters)
        {
            var uploadPath = parameters["UploadPath"].ToString();
            var isDirectory = IsDirectoryUploadPath(uploadPath);

            var sharepointUrl = parameters["SharepointUrl"].ToString();
            var folder = parameters["SPFolderToUpload"].ToString();

            try
            {
                currentAction.Description = "Connection to Sharepoint Web Site";
                ClientContext = new ClientContext(sharepointUrl);
                ClientContext.RequestTimeout = 3600000;

                var web = ClientContext.Web;
                ClientContext.Load(web);

                var listName = parameters["ListName"].ToString();
                currentAction.Description = "Loading List";
                List documentsList = web.Lists.GetByTitle(listName);

                ClientContext.Load(documentsList);
                ClientContext.ExecuteQuery();

                currentAction.Description = string.Format("List '{0}' loaded", listName);

                if (isDirectory)
                {
                    currentAction.Description = string.Format("All files in folder {0} will be uploaded", uploadPath);
                    var searchPatternFile = parameters.ContainsKey("SearchPatternFile") ? parameters["SearchPatternFile"].ToString() : null;

                    foreach (var file in Directory.GetFiles(uploadPath, searchPatternFile, SearchOption.TopDirectoryOnly))
                        UploadFile(file, documentsList, folder, currentAction);
                }
                else
                    UploadFile(uploadPath, documentsList, folder, currentAction);

                currentAction.Description = "Uploading files";
                ClientContext.ExecuteQuery();
            }
            finally
            {
                ClientContext.Dispose();
            }
        }

        private bool IsDirectoryUploadPath(string uploadPath)
        {
            if (!Directory.Exists(uploadPath) && !System.IO.File.Exists(uploadPath))
                throw new Exception(string.Format("Upload path {0} does not exist.", uploadPath));

            return Directory.Exists(uploadPath);
        }

        private static void UploadFile(string fileName, List documentsList, string folder, ICurrentAction currentAction)
        {
            currentAction.Description = string.Format("Starting upload: {0}", fileName);
            var currentFolder = documentsList.RootFolder;
            ClientContext.Load(currentFolder);
            ClientContext.ExecuteQuery();

            foreach (var item in folder.Split(new[] { '/' }))
            {
                if (item == currentFolder.Name) continue;

                currentFolder = GetSharepointFolder(item, currentFolder);

                if (currentFolder == null)
                    throw new DirectoryNotFoundException(string.Format("Folder {0} was not found on server", folder));
            }

            var uploadPath = string.Format("{0}/{1}", currentFolder.ServerRelativeUrl, Path.GetFileName(fileName));

            using (var fileSystem = new FileStream(fileName, FileMode.Open))
                Microsoft.SharePoint.Client.File.SaveBinaryDirect(ClientContext, uploadPath, fileSystem, true);

            //var fileCreationInformation = new FileCreationInformation();

            //fileCreationInformation.Content = System.IO.File.ReadAllBytes(fileName);
            //fileCreationInformation.Url = Path.GetFileName(fileName);
            //fileCreationInformation.Overwrite = true;

            //var uploadFile = currentFolder.Files.Add(fileCreationInformation);

            //ClientContext.Load(uploadFile);
            currentAction.Description = "Upload finished";
        }

        private static Folder GetSharepointFolder(string folder, Folder currentFolder)
        {
            ClientContext.Load(currentFolder.Folders);
            ClientContext.ExecuteQuery();

            return currentFolder.Folders.ToList().FirstOrDefault(x => x.Name == folder);
        }

        public void Stop(ref ICurrentAction currentAction, Dictionary<string, object> parameters)
        {

        }
    }
}

